package com.java.module.chat.util.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.GenericFutureListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * NettyServer
 * 
 * @author yilabao
 * @date 2021年9月28日
 */
public class NettyServer {

    private static final Logger LOG = LoggerFactory.getLogger(NettyServer.class);

    private final String host;

    private final Integer port;

    private final String path;

    private Channel serverChannel;

    public NettyServer(String host, Integer port, String path) {
        this.host = host;
        this.port = port;
        this.path = path;
    }

    public void start() {
        NioEventLoopGroup mainGroup = new NioEventLoopGroup();
        NioEventLoopGroup subGroup = new NioEventLoopGroup();
        ServerBootstrap server = new ServerBootstrap();
        try {
            server.group(mainGroup, subGroup);
            server.channel(NioServerSocketChannel.class);
            server.childHandler(new NettyChannelInitializer(path));
            ChannelFuture channelFuture = server.bind(host, port).sync();
            channelFuture.addListener(new GenericFutureListener<ChannelFuture>() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    LOG.info("Netty init over, result is {} host is {} port is {} path is {}.", future.isSuccess(),
                            host, port, path);
                }
            });
            serverChannel = channelFuture.channel();
            serverChannel.closeFuture().sync();
        } catch (InterruptedException e) {
            LOG.error(e.getMessage(), e);
        } finally {
            mainGroup.shutdownGracefully();
            subGroup.shutdownGracefully();
        }
    }

    public void stop() {
        if (serverChannel != null) {
            serverChannel.close();
        }
    }

}